package zcj.stu;

import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.boot.*;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.*;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.io.ClassPathResource;

import java.util.Arrays;
import java.util.Map;

@Configuration
public class C39_2And8_11 {
    public static void main(String[] args) throws Exception {
        SpringApplication springApplication = new SpringApplication();
        springApplication.addInitializers(new ApplicationContextInitializer<ConfigurableApplicationContext>() {
            @Override
            public void initialize(ConfigurableApplicationContext applicationContext) {
                System.out.println("加载------initialize...");
            }
        });
        System.out.println("----------------------- 2.封装args");
        DefaultApplicationArguments arguments=new DefaultApplicationArguments(args);
        System.out.println("----------------------- 8.封装创建容器");
        GenericApplicationContext context = creatContextByType(WebApplicationType.SERVLET);
        System.out.println("----------------------- 9.封装准备容器");
        for (ApplicationContextInitializer initializer : springApplication.getInitializers()) {
             initializer.initialize(context);
        }
        for (String name : context.getBeanDefinitionNames()) {
            System.out.println(name+" 来源："+context.getBeanDefinition(name).getResourceDescription());
        }
        System.out.println("----------------------- 10.加载bean定义");
        DefaultListableBeanFactory beanFactory = context.getDefaultListableBeanFactory();
        AnnotatedBeanDefinitionReader reader=new AnnotatedBeanDefinitionReader(beanFactory);
        reader.register(WebConfig.class);
        XmlBeanDefinitionReader reader1=new XmlBeanDefinitionReader(beanFactory);
        reader1.loadBeanDefinitions(new ClassPathResource("z1.xml"));
        ClassPathBeanDefinitionScanner scanner=new ClassPathBeanDefinitionScanner(beanFactory);
        scanner.scan("zcj.stu");
        System.out.println("----------------------- 11.refresh容器");
        context.refresh();//准备bean处理器 初始化单例
        for (String name : context.getBeanDefinitionNames()) {
            System.out.println(name+" 来源："+context.getBeanDefinition(name).getResourceDescription());
        }
        System.out.println("----------------------- 12.执行runner");
        Map<String, CommandLineRunner> commandLineRunners = context.getBeansOfType(CommandLineRunner.class);
        for (CommandLineRunner value : commandLineRunners.values()) {
            value.run(args);
        }
        Map<String, ApplicationRunner> applicationRunners= context.getBeansOfType(ApplicationRunner.class);
        for (ApplicationRunner value : applicationRunners.values()) {
            value.run(arguments);
        }
        context.close();
    }
    public static GenericApplicationContext creatContextByType(WebApplicationType type){
                  GenericApplicationContext context=null;
                  switch (type){
                      case SERVLET: context=new AnnotationConfigServletWebServerApplicationContext();
                      case REACTIVE: context=new ReactiveWebServerApplicationContext();
                      case NONE: context=new AnnotationConfigApplicationContext();
                  }
                  return context;
    }
    static class Zcj{}
    static class Zcg{}
    static class Zzz{}
    @Configuration
    static class WebConfig{
        @Bean
        public Zcj zcj(){
            return new Zcj();
        }
        @Bean
        public ServletWebServerFactory webServerFactory(){
            return new TomcatServletWebServerFactory();
        }
        @Bean
        public CommandLineRunner commandLineRunner(){
               return args -> System.out.println("--commandLineRunner "+"args:"+ Arrays.toString(args));
        }
        @Bean
        public ApplicationRunner applicationRunner(){
            return args -> System.out.println("--commandLineRunner "+"args:"+Arrays.toString(args.getSourceArgs()));
        }
    }
}
